import mqtt, { MqttClient } from 'mqtt';
import { config } from '../config';
import { DeviceData, MqttMessage } from '../types';
import { DataProcessor } from './DataProcessor';

export class MqttService {
  private client: MqttClient | null = null;
  private dataProcessor: DataProcessor;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 5;

  constructor() {
    this.dataProcessor = new DataProcessor();
  }

  async initialize(): Promise<void> {
    return new Promise((resolve, reject) => {
      try {
        const options: any = {
          clientId: config.mqtt.clientId,
          clean: true,
          reconnectPeriod: 5000,
          connectTimeout: 30 * 1000,
        };

        if (config.mqtt.username) {
          options.username = config.mqtt.username;
        }
        if (config.mqtt.password) {
          options.password = config.mqtt.password;
        }

        this.client = mqtt.connect(config.mqtt.brokerUrl, options);

        this.client.on('connect', () => {
          console.log('🔗 MQTT 客户端已连接');
          this.reconnectAttempts = 0;
          this.subscribeToTopics();
          resolve();
        });

        this.client.on('message', this.handleMessage.bind(this));
        this.client.on('error', this.handleError.bind(this));
        this.client.on('reconnect', this.handleReconnect.bind(this));
        this.client.on('close', this.handleClose.bind(this));

      } catch (error) {
        reject(error);
      }
    });
  }

  private subscribeToTopics(): void {
    if (!this.client) return;

    // 订阅设备数据主题（可以根据需要修改主题模式）
    const topics = [
      'testzqh/devices/+/data',      // 测试用设备数据
      'testzqh/devices/+/status',    // 测试用设备状态
      'testzqh/devices/+/alarm',     // 测试用设备告警
    ];

    topics.forEach(topic => {
      this.client!.subscribe(topic, { qos: 1 }, (err) => {
        if (err) {
          console.error(`❌ 订阅主题失败 ${topic}:`, err);
        } else {
          console.log(`✅ 已订阅主题: ${topic}`);
        }
      });
    });
  }

  private async handleMessage(topic: string, payload: Buffer, packet: any): Promise<void> {
    try {
      const message: MqttMessage = {
        topic,
        payload,
        qos: packet.qos,
        retain: packet.retain,
      };

      console.log(`📨 收到MQTT消息 - 主题: ${topic}`);
      
      // 处理消息数据
      await this.dataProcessor.processMessage(message);
      
    } catch (error) {
      console.error('❌ 处理MQTT消息失败:', error);
    }
  }

  private handleError(error: Error): void {
    console.error('❌ MQTT 连接错误:', error);
  }

  private handleReconnect(): void {
    this.reconnectAttempts++;
    console.log(`🔄 MQTT 重连尝试 ${this.reconnectAttempts}/${this.maxReconnectAttempts}`);
    
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('❌ MQTT 重连次数超过限制，停止重连');
      this.client?.end();
    }
  }

  private handleClose(): void {
    console.log('🔌 MQTT 连接已关闭');
  }

  // 发布消息（用于向设备发送指令）
  async publish(topic: string, message: string | Buffer, options?: any): Promise<void> {
    return new Promise((resolve, reject) => {
      if (!this.client || !this.client.connected) {
        reject(new Error('MQTT 客户端未连接'));
        return;
      }

      this.client.publish(topic, message, options || { qos: 1 }, (err) => {
        if (err) {
          reject(err);
        } else {
          console.log(`📤 消息已发布到主题: ${topic}`);
          resolve();
        }
      });
    });
  }

  async disconnect(): Promise<void> {
    return new Promise((resolve) => {
      if (this.client) {
        this.client.end(false, {}, () => {
          console.log('🔌 MQTT 客户端已断开连接');
          resolve();
        });
      } else {
        resolve();
      }
    });
  }

  // 获取连接状态
  isConnected(): boolean {
    return this.client?.connected || false;
  }
}
